//
//  CoreTextLabel.m
//  IfengNews
//
//  Created by 侯 甲 on 13-8-22.
//
//

#import "CoreTextLabel.h"
#import "INHtmlElement.h"
#import "IDocHyperLinkButton.h"

#define DEFAULT_FONT_SIZE (17.0f)

@interface CoreTextLabel ()

@property(nonatomic,assign)CTFrameRef frameRef;
@property(nonatomic,assign)CGFloat textLabelHeight;
@property(nonatomic,strong) NSMutableArray *buttons;

- (void)_calcTextLableHeight:(CTFramesetterRef)framesetter;
- (void)_fitoutParagraphWithAttributeText;

@end

@implementation CoreTextLabel

- (void)dealloc
{
    if (_frameRef != NULL) {
        CFRelease(_frameRef);
    }
}

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        _textAttribute = nil;
        _frameRef = NULL;
        _textLabelHeight = 0.0f;
        _textFontSize = DEFAULT_FONT_SIZE;
        self.textFont = [UIFont systemFontOfSize:_textFontSize];
    }
    return self;
}

- (NSAttributedString *)setTextAttribute:(NSString *)string withFont:(UIFont *)font withFontColor:(UIColor *)fontColor{
    self.textAttribute = [[NSMutableAttributedString alloc] initWithString:string];
    if (fontColor) {
        [_textAttribute addAttribute:(id)kCTForegroundColorAttributeName value:(id)fontColor.CGColor range:NSMakeRange(0, _textAttribute.length)];
    }
    if (font) {
        [_textAttribute addAttribute:(id)kCTFontAttributeName value:(__bridge id)(CGFontRef)CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL) range:NSMakeRange(0, _textAttribute.length)];
    }
    return [_textAttribute copy];
}

- (NSAttributedString *)appendTextAttribute:(NSString *)string withFont:(UIFont *)font withFontColor:(UIColor *)fontColor{
    NSMutableAttributedString *tempAttrStr = [[NSMutableAttributedString alloc] initWithString:string];
    if (fontColor) {
        [tempAttrStr addAttribute:(id)kCTForegroundColorAttributeName value:(id)fontColor.CGColor range:NSMakeRange(0, tempAttrStr.length)];
    }
    if (font) {
        [tempAttrStr addAttribute:(id)kCTFontAttributeName value:(__bridge id)(CGFontRef)CTFontCreateWithName((__bridge CFStringRef)font.fontName, font.pointSize, NULL) range:NSMakeRange(0, tempAttrStr.length)];
    }
    [_textAttribute appendAttributedString:tempAttrStr];
    return [_textAttribute copy];
}



- (void)textAttributeComplete{
    [self setNeedsDisplay];
}

- (CGFloat)textLabelHeightWithSelfBounds{
    if (!_textAttribute) {
        NSLog(@"请先设置AttributeString，再请求所占高度！");
        return 0;
    }
    CTFramesetterRef framesetterTemp = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)_textAttribute);
    [self _calcTextLableHeight:framesetterTemp];
    if (framesetterTemp != NULL) {
        CFRelease(framesetterTemp);
    }
    return _textLabelHeight;
}


//- (void)setLinkAble:(CTFrameRef )frame{
//    CFArrayRef array=CTFrameGetLines(frame);
//    CFIndex n=CFArrayGetCount(array);
//    
// 
//    
//    
//    UIFont *font=[UIFont systemFontOfSize:TEXT_FONT_NORMARL_SIZE+[Globle shareInstance].textFontSizeLevel];
//
//    
//    NSMutableArray *arr=[NSMutableArray array];
//    NSMutableArray *arr2=[NSMutableArray array];
//    
//    
//    CGPoint* lineOrigins = malloc(sizeof(CGPoint)*CFArrayGetCount(array));
//    
//    CTFrameGetLineOrigins(frame, CFRangeMake(0,0), lineOrigins);
//    
//    float height=self.bounds.size.height;
//    
//    NSMutableArray *linkAbleArray=[NSMutableArray arrayWithArray:_element.links];
//    
//    int locationOff=0;
//    for(CFIndex i=0;i<n;i++){
//        CTLineRef line=CFArrayGetValueAtIndex(array, i);
//        
//        CGPoint origin = lineOrigins[i];
//        origin.y=height-origin.y-font.lineHeight;
//   
//        
//        CFRange lineRange=CTLineGetStringRange(line);
//        if(i==0){
//            locationOff=lineRange.location;
//        }
//       // lineRange.location-=locationOff;
//        for(NSDictionary *link in linkAbleArray){
//            BOOL b=NO;
//            NSRange range0=[[link sgrGetType:[NSValue class] forKey:@"range"] rangeValue];
//            NSRange range=range0;
//            range.location+=locationOff;
//            if(range.location>=lineRange.location && range.location<lineRange.location+lineRange.length){
//                
//                
//                CGFloat secondaryOffset;
//                CGFloat offset=CTLineGetOffsetForStringIndex(line, range.location, &secondaryOffset);
//         
//                
//                if(i==0){
//                    offset+=origin.x;
//                }
//                CFIndex endLocation=range.location+range.length-1;
//                
//                CGFloat offsetend=0.0f;
//                CGFloat secondaryOffsetEnd;
//                if(endLocation+1<lineRange.location+lineRange.length){
//                    offsetend=CTLineGetOffsetForStringIndex(line, endLocation+1, &secondaryOffsetEnd);
//                }else{
//                   int addLength= endLocation-(lineRange.location+lineRange.length-1);
//                    NSDictionary *dic=[link sgrGetDictionaryForKey:@"link"];
//                    [linkAbleArray sgrAddObject:
//  @{@"range":[NSValue valueWithRange:NSMakeRange(lineRange.location+lineRange.length, addLength)],
//    @"link":dic}];
//                   
//                    offsetend=self.bounds.size.width;
//                    b=YES;
//                    
//                }
//                
//                if(i==0){
//                    offsetend+=2* (TEXT_FONT_NORMARL_SIZE+[Globle shareInstance].textFontSizeLevel);
//                }
//                
//                [arr2 sgrAddObject:[link sgrGetDictionaryForKey:@"link"]];
//                [arr sgrAddObject:
//                 [NSValue valueWithCGRect:CGRectMake(offset, origin.y, offsetend-offset, font.lineHeight+8.0f)]];
//                if(b)break;
//            }
//        }
//      
//    }
//    free(lineOrigins);
//    
//    if(!self.buttons){
//        self.buttons=[NSMutableArray arrayWithCapacity:4];
//    }
//    int left=0;
//     n=[arr count];
//    if(self.buttons.count>0){
//        for(left=0;left<n;left++){
//            IDocHyperLinkButton *hyper=[self.buttons sgrGetType:[UIButton class] forIndex:left];
//            [hyper removeFromSuperview];
//            if(!hyper)break;
//            hyper.link=[arr2 sgrGetDictionaryForIndex:left];
//            CGRect frame=[[arr sgrGetType:[NSValue class] forIndex:left] CGRectValue];
//            hyper.frame=frame;
//            [self addSubview:hyper];
//            
//        }
//    }
//    
//    
//    for(;left<n;left++){
//        IDocHyperLinkButton *hyper=[IDocHyperLinkButton buttonWithType:UIButtonTypeCustom];
//        [hyper initAction];
//
//        hyper.link=[arr2 sgrGetDictionaryForIndex:left];
//        CGRect frame=[[arr sgrGetType:[NSValue class] forIndex:left] CGRectValue];
//        hyper.frame=frame;
//        
//               [self.buttons sgrAddObject:hyper];
//        [self addSubview:hyper];
//    }
//    
//
//    
//}

- (void)setElement:(INHtmlElement *)element{
    _element=element;
    self.frameRef=NULL;
}

- (void)drawRect:(CGRect)rect{
    
    if (self.frameRef == NULL) {
        // 基本样式配置
       // [self _fitoutParagraphWithAttributeText];
        
        // 创建frame
       // CTFramesetterRef framesetterTemp = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)_textAttribute);
        CGMutablePathRef path=CGPathCreateMutable();
        CGPathAddRect(path, NULL, self.bounds);
        CTFrameRef frameRef = CTFramesetterCreateFrame(self.documentModel.framesetter, CFRangeMake(self.element.textRange.location, self.element.textRange.length), path, NULL);
        
        self.frameRef = frameRef;
        
        if (frameRef) {
            CFRelease(frameRef);
        }
        if (path) {
            
            CFRelease(path);
        }
//        if (framesetterTemp) {
//            CFRelease(framesetterTemp);
//        }
    }
    
    CGContextRef context=UIGraphicsGetCurrentContext();
    CGContextSetTextMatrix(context, CGAffineTransformIdentity);
    CGContextSaveGState(context);
    CGContextTranslateCTM(context, 0, self.bounds.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    
    
    CTFrameDraw(_frameRef, context);
    CGContextRestoreGState(context);
//    if(_element.links){
//        [self setLinkAble:_frameRef];
//    }else if (self.buttons && self.buttons.count>0 ){
//        IDocHyperLinkButton *hyper=[IDocHyperLinkButton buttonWithType:UIButtonTypeCustom];
//        [hyper removeFromSuperview];
//    }
}

//// 会刷新 CTFrameRef
//- (void)setElement:(INHTMLElement *)element{
//    if (element.needReDraw == NO && element == _element) {
//        return;
//    }
//    element.needReDraw = NO;
//    _element = element;
//    self.frameRef = [element ctframe:self.bounds];
//}

- (void)setFrameRef:(CTFrameRef)frameRef{
    
    if (frameRef == _frameRef) {
        return;
    }
    if (frameRef != NULL) {
        CFRetain(frameRef);
    }
    if (_frameRef != NULL) {
        CFRelease(_frameRef);
    }
    _frameRef = frameRef;
    if (frameRef == NULL) {
        return;
    }
    self.textAttribute = nil;
    [self setNeedsDisplay];
}

- (void)setTextAttribute:(NSMutableAttributedString *)textAttribute{
    if ([textAttribute isEqualToAttributedString:_textAttribute]) {
        return;
    }
    _textAttribute = [textAttribute mutableCopy];

    if (textAttribute == nil) {
        return;
    }
    
    self.frameRef = NULL;
    
    [self setNeedsDisplay];
}

- (void)setTextFont:(UIFont *)textFont{
    if (textFont == _textFont) {
        return;
    }
    _textFont = textFont;
    
    _textFontSize = textFont.pointSize;
}

/**
 * @abstract 传进来的是NSMutableAttributeString 需要进行最基本的样式配置
 * @note 首行缩进两个字，段落对齐方式：左右对齐
 */
- (void)_fitoutParagraphWithAttributeText{
    //首行缩进
    CTParagraphStyleSetting fristline;
    CGFloat fristlineindent = 2*_textFontSize;
    fristline.spec = kCTParagraphStyleSpecifierFirstLineHeadIndent;
    fristline.value = &fristlineindent;
    fristline.valueSize = sizeof(float);
    // 对齐方式
    CTParagraphStyleSetting alignmentStyle;
    CTTextAlignment alignment = kCTJustifiedTextAlignment;
    alignmentStyle.spec=kCTParagraphStyleSpecifierAlignment;
    alignmentStyle.valueSize=sizeof(alignment);
    alignmentStyle.value=&alignment;
    //换行模式
    CTParagraphStyleSetting lineBreakMode;
    CTLineBreakMode lineBreak = kCTLineBreakByWordWrapping;
    lineBreakMode.spec = kCTParagraphStyleSpecifierLineBreakMode;
    lineBreakMode.value = &lineBreak;
    lineBreakMode.valueSize = sizeof(CTLineBreakMode);
    //行距
    CTParagraphStyleSetting lineSpaceSetting;
    CGFloat _linespace = 4.0f;
    lineSpaceSetting.spec = kCTParagraphStyleSpecifierLineSpacing;
    lineSpaceSetting.value = &_linespace;
    lineSpaceSetting.valueSize = sizeof(float);
    
    //组合设置
    CTParagraphStyleSetting settings[] = {
        fristline,
        alignmentStyle,
        lineBreakMode,
        lineSpaceSetting,
    };
    //通过设置项产生段落样式对象
    CTParagraphStyleRef style = CTParagraphStyleCreate(settings, 4);
    [_textAttribute addAttribute:(id)kCTParagraphStyleAttributeName value:(__bridge id)style range:NSMakeRange(0, _textAttribute.length)];
}

- (void)_calcTextLableHeight:(CTFramesetterRef)framesetter{
    CGSize textLabelSize = CTFramesetterSuggestFrameSizeWithConstraints(framesetter,
                                                                        CFRangeMake(0, _textAttribute.length),
                                                                        NULL,
                                                                        CGSizeMake(CGRectGetWidth(self.frame), CGFLOAT_MAX),
                                                                        NULL);
    _textLabelHeight = textLabelSize.height;
}

- (CTFrameRef)ctFrameRef{
    if (self.frameRef == NULL) {
        // 基本样式配置
        // [self _fitoutParagraphWithAttributeText];
        
        // 创建frame
        // CTFramesetterRef framesetterTemp = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)_textAttribute);
        CGMutablePathRef path=CGPathCreateMutable();
        CGPathAddRect(path, NULL, self.bounds);
        CTFrameRef frameRef = CTFramesetterCreateFrame(self.documentModel.framesetter, CFRangeMake(self.element.textRange.location, self.element.textRange.length), path, NULL);
        
        self.frameRef = frameRef;
        
        if (frameRef) {
            CFRelease(frameRef);
        }
        if (path) {
            
            CFRelease(path);
        }
        //        if (framesetterTemp) {
        //            CFRelease(framesetterTemp);
        //        }
    }

    return self.frameRef;
}

@end
